package com.example.stuwork.service.impl;

import com.example.stuwork.common.Result;
import com.example.stuwork.dao.AssignmentAllocationDao;
import com.example.stuwork.dao.AssignmentAllocationStats;
import com.example.stuwork.dao.AssignmentDao;
import com.example.stuwork.pojo.Assignment;
import com.example.stuwork.pojo.AssignmentAllocation;
import com.example.stuwork.service.AssignmentAllocationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 作业分配服务实现类
 */
@Service
public class AssignmentAllocationServiceImpl implements AssignmentAllocationService {
    
    private static final Logger logger = LoggerFactory.getLogger(AssignmentAllocationServiceImpl.class);
    
    @Autowired
    private AssignmentAllocationDao assignmentAllocationDao;

    @Autowired
    private AssignmentDao assignmentDao;

    @Override
    public Result<AssignmentAllocation> getAllocationById(Long allocationId) {
        try {
            AssignmentAllocation allocation = assignmentAllocationDao.getById(allocationId);
            if (allocation == null) {
                return Result.error("作业分配记录不存在");
            }
            return Result.success(allocation);
        } catch (Exception e) {
            logger.error("获取作业分配记录失败，分配ID: " + allocationId, e);
            return Result.error("获取作业分配记录失败: " + e.getMessage());
        }
    }

    @Override
    public Result<List<AssignmentAllocation>> getAllocationsByAssignmentId(Long assignmentId) {
        try {
            List<AssignmentAllocation> allocations = assignmentAllocationDao.findByAssignmentId(assignmentId);
            return Result.success(allocations);
        } catch (Exception e) {
            logger.error("获取作业分配记录列表失败，作业ID: " + assignmentId, e);
            return Result.error("获取作业分配记录列表失败: " + e.getMessage());
        }
    }

    @Override
    public Result<List<AssignmentAllocation>> getAllocationsByStudentId(String studentId) {
        try {
            List<AssignmentAllocation> allocations = assignmentAllocationDao.findByStudentId(studentId);
            return Result.success(allocations);
        } catch (Exception e) {
            logger.error("获取学生作业分配记录列表失败，学生ID: " + studentId, e);
            return Result.error("获取学生作业分配记录列表失败: " + e.getMessage());
        }
    }

    @Override
    public Result<AssignmentAllocation> getAllocationByAssignmentIdAndStudentId(Long assignmentId, String studentId) {
        try {
            AssignmentAllocation allocation = assignmentAllocationDao.findByAssignmentIdAndStudentId(assignmentId, studentId);
            if (allocation == null) {
                return Result.error("作业分配记录不存在");
            }
            return Result.success(allocation);
        } catch (Exception e) {
            logger.error("获取作业分配记录失败，作业ID: " + assignmentId + ", 学生ID: " + studentId, e);
            return Result.error("获取作业分配记录失败: " + e.getMessage());
        }
    }

    @Override
    public Result<List<AssignmentAllocation>> getAllocationsByAssignmentIdAndStatus(Long assignmentId, Integer status) {
        try {
            List<AssignmentAllocation> allocations = assignmentAllocationDao.findByAssignmentIdAndStatus(assignmentId, status);
            return Result.success(allocations);
        } catch (Exception e) {
            logger.error("获取作业分配记录列表失败，作业ID: " + assignmentId + ", 状态: " + status, e);
            return Result.error("获取作业分配记录列表失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<AssignmentAllocation> addAllocation(AssignmentAllocation allocation) {
        try {
            assignmentAllocationDao.insert(allocation);
            return Result.success(allocation);
        } catch (Exception e) {
            logger.error("添加作业分配记录失败", e);
            return Result.error("添加作业分配记录失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<Boolean> batchAddAllocations(List<AssignmentAllocation> allocations) {
        try {
            assignmentAllocationDao.batchInsert(allocations);
            return Result.success("批量添加作业分配记录成功", true);
        } catch (Exception e) {
            logger.error("批量添加作业分配记录失败", e);
            return Result.error("批量添加作业分配记录失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<AssignmentAllocation> updateAllocation(AssignmentAllocation allocation) {
        try {
            AssignmentAllocation existingAllocation = assignmentAllocationDao.getById(allocation.getAllocationId());
            if (existingAllocation == null) {
                return Result.error("作业分配记录不存在");
            }
            
            assignmentAllocationDao.update(allocation);
            return Result.success(allocation);
        } catch (Exception e) {
            logger.error("更新作业分配记录失败，分配ID: " + allocation.getAllocationId(), e);
            return Result.error("更新作业分配记录失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<Boolean> updateAllocationStatus(Long allocationId, Integer status) {
        try {
            AssignmentAllocation existingAllocation = assignmentAllocationDao.getById(allocationId);
            if (existingAllocation == null) {
                return Result.error("作业分配记录不存在");
            }
            
            assignmentAllocationDao.updateStatus(allocationId, status);
            return Result.success("更新作业分配记录状态成功", true);
        } catch (Exception e) {
            logger.error("更新作业分配记录状态失败，分配ID: " + allocationId, e);
            return Result.error("更新作业分配记录状态失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<Boolean> updateSubmissionId(Long allocationId, Long submissionId, Integer status) {
        try {
            AssignmentAllocation existingAllocation = assignmentAllocationDao.getById(allocationId);
            if (existingAllocation == null) {
                return Result.error("作业分配记录不存在");
            }
            
            assignmentAllocationDao.updateSubmissionId(allocationId, submissionId, status);
            return Result.success("更新作业提交ID成功", true);
        } catch (Exception e) {
            logger.error("更新作业提交ID失败，分配ID: " + allocationId, e);
            return Result.error("更新作业提交ID失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<Boolean> updateScore(Long allocationId, Integer score) {
        try {
            AssignmentAllocation existingAllocation = assignmentAllocationDao.getById(allocationId);
            if (existingAllocation == null) {
                return Result.error("作业分配记录不存在");
            }
            
            assignmentAllocationDao.updateScore(allocationId, score);
            return Result.success("更新作业分配记录评分成功", true);
        } catch (Exception e) {
            logger.error("更新作业分配记录评分失败，分配ID: " + allocationId, e);
            return Result.error("更新作业分配记录评分失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<Boolean> deleteAllocation(Long allocationId) {
        try {
            AssignmentAllocation existingAllocation = assignmentAllocationDao.getById(allocationId);
            if (existingAllocation == null) {
                return Result.error("作业分配记录不存在");
            }
            
            assignmentAllocationDao.delete(allocationId);
            return Result.success("删除作业分配记录成功", true);
        } catch (Exception e) {
            logger.error("删除作业分配记录失败，分配ID: " + allocationId, e);
            return Result.error("删除作业分配记录失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<Boolean> deleteAllocationsByAssignmentId(Long assignmentId) {
        try {
            assignmentAllocationDao.deleteByAssignmentId(assignmentId);
            return Result.success("删除作业相关分配记录成功", true);
        } catch (Exception e) {
            logger.error("删除作业相关分配记录失败，作业ID: " + assignmentId, e);
            return Result.error("删除作业相关分配记录失败: " + e.getMessage());
        }
    }

    @Override
    public Result<AssignmentAllocationStats> getAssignmentStats(Long assignmentId) {
        try {
            AssignmentAllocationStats stats = assignmentAllocationDao.getStatsByAssignmentId(assignmentId);
            return Result.success(stats);
        } catch (Exception e) {
            logger.error("获取作业统计信息失败，作业ID: " + assignmentId, e);
            return Result.error("获取作业统计信息失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<Boolean> syncAssignmentsForNewStudent(String studentId, Long classId) {
        try {
            // 参数校验
            if (studentId == null || studentId.isEmpty() || classId == null) {
                return Result.error("学生ID或班级ID参数无效");
            }
            
            // 查询班级所有有效的作业
            List<Assignment> activeAssignments = assignmentDao.findActiveAssignmentsByClassId(classId);
            
            if (activeAssignments.isEmpty()) {
                logger.info("班级 {} 没有有效作业需要分配给学生 {}", classId, studentId);
                return Result.success("没有有效作业需要分配", true);
            }
            
            logger.info("为新学生 {} 分配 {} 个作业", studentId, activeAssignments.size());
            
            // 创建批量插入的分配列表
            List<AssignmentAllocation> allocationsToAdd = new ArrayList<>();
            
            // 为每个作业创建分配记录
            for (Assignment assignment : activeAssignments) {
                // 检查是否已经存在分配记录
                boolean exists = assignmentAllocationDao.existsByAssignmentIdAndStudentId(
                    assignment.getAssignmentId(), studentId);
                    
                if (!exists) {
                    // 使用构造函数创建新的分配记录
                    AssignmentAllocation allocation = new AssignmentAllocation(assignment.getAssignmentId(), studentId);
                    // 确保状态设置为未提交
                    allocation.setStatus(0);
                    
                    allocationsToAdd.add(allocation);
                    
                    logger.info("为新学生 {} 创建作业分配：作业ID={}, 标题={}", 
                        studentId, assignment.getAssignmentId(), assignment.getTitle());
                } else {
                    logger.info("学生 {} 已存在作业分配：作业ID={}", 
                        studentId, assignment.getAssignmentId());
                }
            }
            
            // 如果有需要添加的分配记录，批量插入
            if (!allocationsToAdd.isEmpty()) {
                assignmentAllocationDao.batchInsert(allocationsToAdd);
                logger.info("成功为学生 {} 添加 {} 个作业分配", studentId, allocationsToAdd.size());
                return Result.success("成功分配" + allocationsToAdd.size() + "个作业", true);
            } else {
                logger.info("学生 {} 已分配所有作业，无需新增", studentId);
                return Result.success("所有作业已分配，无需新增", true);
            }
        } catch (Exception e) {
            logger.error("为新学生分配作业时发生错误，学生ID: " + studentId + ", 班级ID: " + classId, e);
            return Result.error("作业分配失败：" + e.getMessage());
        }
    }
} 